package xyz.xtt.asset.service.impl;

import static java.util.stream.Collectors.toMap;
import static xyz.xtt.common.asset.AssertUtils.isFalse;
import static xyz.xtt.common.asset.AssertUtils.isNull;
import static xyz.xtt.common.asset.AssertUtils.isTrue;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.google.common.primitives.Longs;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import xyz.xtt.asset.api.enums.AssetNoStatusEnum;
import xyz.xtt.asset.api.enums.AssetNoTypeEnum;
import xyz.xtt.asset.api.enums.SellPatternEnum;
import xyz.xtt.asset.api.enums.StatusAllEnum;
import xyz.xtt.asset.client.request.AssetNoInfoRequest;
import xyz.xtt.asset.client.request.CardInfoRequest;
import xyz.xtt.asset.client.response.AssetNoResponse;
import xyz.xtt.asset.client.response.TblAssetNoDto;
import xyz.xtt.asset.constants.ErrorMessage;
import xyz.xtt.asset.entity.AssetNoTransRecord;
import xyz.xtt.asset.entity.TblAssetCard;
import xyz.xtt.asset.entity.TblAssetNo;
import xyz.xtt.asset.entity.TblAssetTransaction;
import xyz.xtt.asset.mapper.TblAssetCardMapper;
import xyz.xtt.asset.mapper.TblAssetNoMapper;
import xyz.xtt.asset.service.IAssetNoTransRecordService;
import xyz.xtt.asset.service.IInnerService;
import xyz.xtt.asset.service.ITblAssetCardService;
import xyz.xtt.asset.service.ITblAssetNoService;
import xyz.xtt.asset.service.ITblAssetService;
import xyz.xtt.asset.service.ITblAssetTransactionService;
import xyz.xtt.asset.utils.RedisLockUtil;
import xyz.xtt.asset.vo.AssetNoMake;
import xyz.xtt.equity.client.request.BlockAssetNoBenefitRequest;
import xyz.xtt.equity.client.request.SendAssetNoBenefitRequest;
import xyz.xtt.equity.client.request.UnBlockAssetNoBenefitRequest;
import xyz.xtt.exchange.client.ExchangeClient;
import xyz.xtt.pay.client.response.BusinessOrderResponse;
import xyz.xtt.pay.client.response.TblPayOrderDto;

/**
 * <p>
 * 资产编号表 服务实现类
 * </p>
 *
 * @author daveafei
 * @since 2025-03-17
 */
@Service
@Slf4j
public class TblAssetNoServiceImpl extends ServiceImpl<TblAssetNoMapper, TblAssetNo> implements ITblAssetNoService {

	@Autowired
	private TblAssetNoMapper tblAssetNoMapper;

	@Autowired
	private ITblAssetCardService tblAssetCardService;

	@Autowired
	private TblAssetCardMapper tblAssetCardMapper;

	@Autowired
	private ITblAssetService iTblAssetService;

	@Autowired
	private IAssetNoTransRecordService iAssetNoTransRecordService;
	@Autowired
	private RedisLockUtil redisLockUtil;
	@Autowired
	private ITblAssetTransactionService iTblAssetTransactionService;
	@Autowired
	private ExchangeClient exchangeClient;
	@Autowired
	private IInnerService iInnerService;

	@Override
	public List<TblAssetNoDto> getNFTNoInfo(AssetNoInfoRequest assetNoInfoRequest) {
		List<TblAssetNoDto> result = new ArrayList<>();
		LambdaQueryWrapper<TblAssetNo> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(TblAssetNo::getAppUserId, assetNoInfoRequest.getOwnerId());
		queryWrapper.eq(TblAssetNo::getAssetType, 0);
		if (assetNoInfoRequest.getAssetId() != null) {
			queryWrapper.eq(TblAssetNo::getAssetId, assetNoInfoRequest.getAssetId());
		}
		List<TblAssetNo> tblAssetNo = tblAssetNoMapper.selectList(queryWrapper);
		CardInfoRequest cardInfoRequest = new CardInfoRequest();
		cardInfoRequest.setOwnerId(assetNoInfoRequest.getOwnerId());
		cardInfoRequest.setAssetNos(tblAssetNo.stream().map(TblAssetNo::getAssetNo).toList());
		cardInfoRequest.setAssetId(assetNoInfoRequest.getAssetId());
		List<TblAssetCard> userCardInfo = tblAssetCardService.getUserCardInfo(cardInfoRequest);
		// card转换成map
		Map<String, TblAssetCard> collect = userCardInfo.stream().collect(toMap(TblAssetCard::getAssetNo, Function.identity(), (v1, v2) -> v1));
		tblAssetNo.forEach(no -> {
			TblAssetNoDto tblAssetNoDto = new TblAssetNoDto();
			BeanUtils.copyProperties(no, tblAssetNoDto);
			try {
				if (collect.containsKey(no.getAssetNo())) {
					TblAssetCard tblAssetCard = collect.get(no.getAssetNo());
					tblAssetNoDto.setCardNo(tblAssetCard.getCardNo());
					tblAssetNoDto.setCardId(tblAssetCard.getId());
					tblAssetNoDto.setReceiveState(tblAssetCard.getReceiveState());
					tblAssetNoDto.setDestoryState(tblAssetCard.getDestoryState());
				}
			} catch (Exception e) {
				log.error("[TblAssetNoServiceImpl][getNFTNoInfo] is error", e);
			}
			;
			result.add(tblAssetNoDto);
		});
		return result;
	}

	@Override
	public void updateAssetCardReceiveState(TblPayOrderDto payOrderDto) {
		BusinessOrderResponse businessOrder = iInnerService.businessOrderInfoWithId(Longs.tryParse(payOrderDto.getBusinessRefId()));
		List<TblAssetNo> tblAssetNos = tblAssetNoMapper.selectList(new LambdaQueryWrapper<TblAssetNo>().eq(TblAssetNo::getId, businessOrder.getGoodsId()));
		LambdaUpdateWrapper<TblAssetCard> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.in(TblAssetCard::getAssetNo, tblAssetNos.stream().map(TblAssetNo::getAssetNo).toList());
		updateWrapper.eq(TblAssetCard::getDestoryState, 0);
		updateWrapper.set(TblAssetCard::getReceiveState, 1);
		int update = tblAssetCardMapper.update(updateWrapper);
		log.info("updateAssetCardReceiveState:{},payOrderDto:{}", update, payOrderDto);
	}

	private TblAssetNo getAssetNoByAssetNoMake(AssetNoMake assetNoMake) {
		return TblAssetNo
				.builder()
				.id(IdUtil.getSnowflakeNextId())
				.assetId(assetNoMake.getAssetId())
				.rootAssetId(assetNoMake.getRootAssetId())
				.assetNo(String.valueOf(iTblAssetService.updateSeqNo(assetNoMake.getRootAssetId(), 1L)))
				.appUserId(assetNoMake.getForm())
				.transactionId(assetNoMake.getTransactionId())
				.assetType(AssetNoTypeEnum.ASSET.getCode())
				.source(assetNoMake.getAssetSource())
				.noStatus(AssetNoStatusEnum.LOCK.getCode())
				.build();
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void syncAssetNoLock(AssetNoMake assetNoMake) {
		log.info("syncAssetNoLock start, assetNoMake:{}", JSONUtil.toJsonStr(assetNoMake));
		// 资产级分布式锁保护
		String lockKey = "assetNoLock:" + assetNoMake.getAssetId();
		String lockValue = IdUtil.fastSimpleUUID();
		boolean acquireLock = false;
		try {
			acquireLock = redisLockUtil.tryLock(lockKey, lockValue, 1, TimeUnit.MINUTES, 5, TimeUnit.SECONDS);
			isFalse(acquireLock, ErrorMessage.ASSET_NO_LOCK_ERROR, () -> log.error("syncAssetNoLock acquireLock failed, assetId:{}", assetNoMake.getAssetId()));

			// 指定编号时对特定的单个编号进行锁定(此时必定是二级交易)
			Long assetNoId = assetNoMake.getAssetNoId();
			if (Objects.nonNull(assetNoId)) {
				syncAssetNoLockWithTheAssetNo(assetNoMake);
				return;
			}

			// 未指定编号时根据购买数量进行锁定（此时可能为一级或二级交易）
			syncAssetNoLockBatch(assetNoMake);
		} finally {
			if (acquireLock) {
				redisLockUtil.releaseLock(lockKey, lockValue);
			}
		}
	}

	/**
	 * 批量锁定资产编号
	 * 
	 * @param assetNoMake
	 * @return
	 */
	private void syncAssetNoLockBatch(AssetNoMake assetNoMake) {
		int assetNoCount = assetNoMake.getPurchaseNum();
		boolean isTopTrade = assetNoMake.isTopTrade();

		if (isTopTrade) {
			// Step1:首先检查卖家是否有闲置的可被锁定的资产编号
			LambdaQueryChainWrapper<TblAssetNo> query = new LambdaQueryChainWrapper<>(baseMapper);
			List<TblAssetNo> assetNoList = query
					.eq(TblAssetNo::getAppUserId, assetNoMake.getForm())
					.eq(TblAssetNo::getAssetId, assetNoMake.getAssetId())
					.eq(TblAssetNo::getNoStatus, AssetNoStatusEnum.IDLE.getCode())
					.eq(TblAssetNo::getAssetType, 0)
					.orderByAsc(TblAssetNo::getAssetNo)
					.last("limit " + assetNoCount)
					.list();

			if (!CollectionUtils.isEmpty(assetNoList)) {
				LambdaUpdateChainWrapper<TblAssetNo> q = new LambdaUpdateChainWrapper<>(baseMapper);
				q
						.in(TblAssetNo::getId, assetNoList.stream().map(TblAssetNo::getId).toList())
						.set(TblAssetNo::getNoStatus, AssetNoStatusEnum.LOCK.getCode())
						.set(TblAssetNo::getTransactionId, assetNoMake.getTransactionId())
						.setIncrBy(TblAssetNo::getVer, 1);
				int update1 = baseMapper.update(q);
				isFalse(update1 == assetNoList.size(), ErrorMessage.ASSET_NO_LOCK_ERROR);
			}

			// Step2:如果闲置的资产编号不足,则新增资产编号
			List<TblAssetNo> needInsertList = new ArrayList<>();
			for (int i = 0; i < assetNoCount - assetNoList.size(); i++) {
				needInsertList.add(getAssetNoByAssetNoMake(assetNoMake));
			}
			if (needInsertList.size() > 0) {
				isFalse(saveBatch(needInsertList), ErrorMessage.ASSET_NO_LOCK_ERROR);
			}
		} else {
			// Step1:从卖家的资产编号中锁定指定数量的编号
			LambdaQueryChainWrapper<TblAssetNo> query = new LambdaQueryChainWrapper<>(baseMapper);
			List<TblAssetNo> assetNoList = query
					.eq(TblAssetNo::getAppUserId, assetNoMake.getForm())
					.eq(TblAssetNo::getAssetId, assetNoMake.getAssetId())
					.eq(TblAssetNo::getNoStatus, AssetNoStatusEnum.NORMAL.getCode())
					.eq(TblAssetNo::getAssetType, 0)
					.orderByAsc(TblAssetNo::getAssetNo)
					.last("limit " + assetNoCount)
					.list();
			isTrue(CollectionUtils.isEmpty(assetNoList) || assetNoList.size() < assetNoCount, ErrorMessage.ASSET_NO_LOCK_ERROR);
			LambdaUpdateChainWrapper<TblAssetNo> update = new LambdaUpdateChainWrapper<>(baseMapper);
			isFalse(update
					.in(TblAssetNo::getId, assetNoList.stream().map(TblAssetNo::getId).toList())
					.set(TblAssetNo::getNoStatus, AssetNoStatusEnum.LOCK.getCode())
					.set(TblAssetNo::getTransactionId, assetNoMake.getTransactionId())
					.setIncrBy(TblAssetNo::getVer, 1)
					.update(), ErrorMessage.ASSET_NO_LOCK_ERROR);
		}
	}

	/**
	 * 锁定卖家确定资产编号
	 * 
	 * @param assetNoMake
	 * @return
	 */
	private void syncAssetNoLockWithTheAssetNo(AssetNoMake assetNoMake) {
		// step1:检查该资产编号是否仍在卖家名下且状态正常
		LambdaQueryChainWrapper<TblAssetNo> query = new LambdaQueryChainWrapper<>(baseMapper);
		TblAssetNo assetNo = query
				.eq(TblAssetNo::getAssetId, assetNoMake.getAssetId())
				.eq(Objects.nonNull(assetNoMake.getAssetNoId()), TblAssetNo::getId, assetNoMake.getAssetNoId())
				.eq(TblAssetNo::getNoStatus, AssetNoStatusEnum.NORMAL.getCode())
				.eq(TblAssetNo::getAppUserId, assetNoMake.getForm())
				.eq(TblAssetNo::getAssetType, 0)
				.orderByAsc(TblAssetNo::getId)
				.one();
		if (Objects.isNull(assetNo)) {
			isNull(assetNo, ErrorMessage.ASSET_NO_LOCK_ERROR);
		}

		// step2:尝试锁定编号
		LambdaUpdateChainWrapper<TblAssetNo> update = new LambdaUpdateChainWrapper<>(baseMapper);
		boolean updateResult = update
				.eq(TblAssetNo::getId, assetNo.getId())
				.eq(TblAssetNo::getVer, assetNo.getVer())
				.set(TblAssetNo::getNoStatus, AssetNoStatusEnum.LOCK.getCode())
				.set(TblAssetNo::getTransactionId, assetNoMake.getTransactionId())
				.set(TblAssetNo::getVer, assetNo.getVer() + 1)
				.update();
		isFalse(updateResult, ErrorMessage.ASSET_NO_LOCK_ERROR);
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void syncAssetNoUnLock(AssetNoMake assetNoMake) {
		List<TblAssetNo> assetNoList = tblAssetNoMapper
				.selectList(new QueryWrapper<TblAssetNo>().lambda().eq(TblAssetNo::getTransactionId, assetNoMake.getTransactionId()).last("for update"));
		if (CollectionUtils.isEmpty(assetNoList)) {
			return;
		}
		isFalse(assetNoList.get(0).getNoStatus().equals(AssetNoStatusEnum.LOCK.getCode()), ErrorMessage.ASSET_NO_UPDATE_ERROR);
		isFalse(assetNoList.get(0).getAssetType().equals(AssetNoTypeEnum.ASSET.getCode()), ErrorMessage.ASSET_NO_UPDATE_ERROR);

		LambdaUpdateChainWrapper<TblAssetNo> updateChainWrapper = new LambdaUpdateChainWrapper<>(tblAssetNoMapper);
		boolean updateResult = updateChainWrapper
				.eq(TblAssetNo::getTransactionId, assetNoMake.getTransactionId())
				.set(TblAssetNo::getNoStatus, AssetNoStatusEnum.NORMAL.getCode())
				.set(TblAssetNo::getAppUserId, assetNoMake.getTo())
				.set(!assetNoMake.isTopTrade(), TblAssetNo::getAssetType, AssetNoTypeEnum.MINT_BENEFIT.getCode())
				.set(TblAssetNo::getUpdateTime, System.currentTimeMillis())
				.set(TblAssetNo::getReceiveTime, System.currentTimeMillis())
				.set(TblAssetNo::getSellPattern, StatusAllEnum.NO.code())
				.setIncrBy(TblAssetNo::getVer, 1)
				.update();
		isFalse(updateResult, ErrorMessage.ASSET_NO_UPDATE_ERROR);

		long now = System.currentTimeMillis();
		List<AssetNoTransRecord> transRecords = new ArrayList<>(assetNoList.size());
		assetNoList.forEach(assetNo -> {
			AssetNoTransRecord transRecord = AssetNoTransRecord
					.builder()
					.id(IdUtil.getSnowflakeNextId())
					.rootAssetId(assetNo.getRootAssetId())
					.assetNo(assetNo.getAssetNo())
					.transactionId(assetNo.getTransactionId())
					.appUserId(assetNoMake.getTo())
					.assetType(assetNoMake.isTopTrade() ? AssetNoTypeEnum.ASSET.getCode() : AssetNoTypeEnum.MINT_BENEFIT.getCode())
					.createTime(now)
					.updateTime(now)
					.build();
			transRecords.add(transRecord);
		});
		isFalse(iAssetNoTransRecordService.saveBatch(transRecords), ErrorMessage.ASSET_NO_UPDATE_ERROR);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void sendAssetCard(long assetNoId, long receiverId) {
		TblAssetNo tblAssetNo = tblAssetNoMapper.selectById(assetNoId);
		isNull(tblAssetNo, ErrorMessage.ASSET_NO_NOT_EXIST);
		isFalse(Objects.equals(tblAssetNo.getAppUserId(), receiverId), ErrorMessage.ASSET_NO_NOT_OWN);
		isFalse(Objects.equals(tblAssetNo.getAssetType(), 0), ErrorMessage.ASSET_NO_STATUS_ERROR);

		// 下发卡牌
		sendAssetCard2User(tblAssetNo);
	}

	/**
	 * 取消资产编号锁定
	 *
	 * @param assetNoMake
	 * @return
	 */
	@Override
	public void syncAssetLockCancel(AssetNoMake assetNoMake) {
		LambdaUpdateChainWrapper<TblAssetNo> update = new LambdaUpdateChainWrapper<>(baseMapper);
		isFalse(update
				.eq(TblAssetNo::getTransactionId, assetNoMake.getTransactionId())
				.set(assetNoMake.isTopTrade(), TblAssetNo::getNoStatus, AssetNoStatusEnum.IDLE.getCode())
				.set(!assetNoMake.isTopTrade(), TblAssetNo::getNoStatus, AssetNoStatusEnum.NORMAL.getCode())
				.setIncrBy(TblAssetNo::getVer, 1)
				.set(TblAssetNo::getUpdateTime, System.currentTimeMillis())
				.update(), ErrorMessage.ASSET_NO_UPDATE_ERROR);
	}

	@Override
	public List<TblAssetNo> getAssetNoByTrans(long transactionId, AssetNoTypeEnum assetNoTypeEnum, AssetNoStatusEnum statusEnum) {
		return new LambdaQueryChainWrapper<>(baseMapper)
				.eq(TblAssetNo::getTransactionId, transactionId)
				.eq(TblAssetNo::getAssetType, assetNoTypeEnum.getCode())
				.eq(TblAssetNo::getNoStatus, statusEnum.getCode())
				.list();
	}

	private void sendAssetCard2User(TblAssetNo tblAssetNo) {
		// 检查该资产编号下是否存在其他卡牌,如果有则作废
		tblAssetCardService.updateUserRepeatCardInvalid(tblAssetNo.getId());
		// 为用户创建新卡牌
		isFalse(tblAssetCardService.insertAssetCard(tblAssetNo), ErrorMessage.ASSET_CARD_RECEIVE_FAILED);
	}

	private TblAssetNo createAssetNo(Long assetId, Long rootAssetId, Long appUserId) {
		TblAssetNo assetNo = TblAssetNo
				.builder()
				.id(IdUtil.getSnowflakeNextId())
				.assetId(assetId)
				.rootAssetId(rootAssetId)
				.assetNo(String.valueOf(iTblAssetService.updateSeqNo(rootAssetId, 1L)))
				.appUserId(appUserId)
				.transactionId(0L)
				.assetType(AssetNoTypeEnum.ASSET.getCode())
				.source("purchase")
				.noStatus(AssetNoStatusEnum.NORMAL.getCode())
				.build();
		baseMapper.insert(assetNo);
		return assetNo;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void rMintAssetNo(Long oldAssetId, Long appUserId, Long asseId, Long rootAssetId) {
		// 根据用户 资产ID 资产锁定状态 查询资产编号
		LambdaQueryChainWrapper<TblAssetNo> query = new LambdaQueryChainWrapper<>(baseMapper);
		TblAssetNo one = query
				.eq(TblAssetNo::getAssetId, oldAssetId)
				.eq(TblAssetNo::getAssetType, AssetNoTypeEnum.MINT_BENEFIT.getCode())
				.eq(TblAssetNo::getAppUserId, appUserId)
				.last("limit 1")
				.one();
		// 不存在，数据补充
		if (Objects.isNull(one)) {
			one = createAssetNo(asseId, rootAssetId, appUserId);
		} else {
			one.setAssetId(asseId);
			one.setAssetType(AssetNoTypeEnum.ASSET.getCode());
			// 修改数据
			isFalse(updateById(one), ErrorMessage.ASSET_NO_UPDATE_ERROR);
			// 修改资产log数据
			iAssetNoTransRecordService.setAssetNoTypeByAssetNo(one.getAssetNo(), one.getAppUserId());
		}

		TblAssetTransaction transaction = iTblAssetTransactionService.getById(one.getTransactionId());
		if (Objects.isNull(transaction)) {
			return;
		}

		// 铸造权铸造后转移权益
		SendAssetNoBenefitRequest sendAssetNoBenefitRequest = new SendAssetNoBenefitRequest();
		sendAssetNoBenefitRequest.setAssetId(rootAssetId);
		sendAssetNoBenefitRequest.setAssetNoIds(List.of(one.getId()));
		sendAssetNoBenefitRequest.setSenderId(Long.valueOf(transaction.getSellerUserId()));
		sendAssetNoBenefitRequest.setReceiverId(appUserId);
		Boolean result = iInnerService.sendAssetNoBenefit(sendAssetNoBenefitRequest);
		isFalse(result, ErrorMessage.ASSET_NO_UPDATE_ERROR);
	}

	@Override
	public AssetNoResponse assetNoInfoWithNoId(Long noId) {
		MPJLambdaWrapper<TblAssetNo> query = JoinWrappers.lambda(TblAssetNo.class).eq(TblAssetNo::getId, noId);
		AssetNoResponse one = query.one(AssetNoResponse.class);
		return one;
	}

	@Override
	public void on(Long assetId, Long uid) {
		// 上架 assetNo数据
		List<TblAssetNo> list = new LambdaQueryChainWrapper<>(baseMapper)
				.eq(TblAssetNo::getAssetId, assetId)
				.eq(TblAssetNo::getAppUserId, uid)
				.eq(TblAssetNo::getSellPattern, SellPatternEnum.NORMAL.code())
				.list();
		if (list.isEmpty()) {
			return;
		}
		// 上架数据
		List<Long> noIds = list.stream().map(TblAssetNo::getId).toList();
		boolean update = new LambdaUpdateChainWrapper<>(baseMapper)
				.in(TblAssetNo::getId, noIds)
				.set(TblAssetNo::getSellPattern, SellPatternEnum.BUY_NOW_PRICE.code())
				.update();
		isFalse(update, ErrorMessage.ASSET_SETTING_EX);
		// 冻结权益
		BlockAssetNoBenefitRequest blockAssetNoBenefitRequest = BlockAssetNoBenefitRequest.builder().assetNodIds(noIds).userId(uid).build();
		Boolean blockAssetNoBenefit = iInnerService.blockAssetNoBenefit(blockAssetNoBenefitRequest);
		log.info("on blockAssetNoBenefit result:{}", blockAssetNoBenefit);
	}

	@Override
	public void off(Long assetId, Long uid) {
		// 下架 assetNo数据
		List<TblAssetNo> list = new LambdaQueryChainWrapper<>(baseMapper)
				.eq(TblAssetNo::getAssetId, assetId)
				.eq(TblAssetNo::getAppUserId, uid)
				.eq(TblAssetNo::getSellPattern, SellPatternEnum.BUY_NOW_PRICE.code())
				.list();
		if (list.isEmpty()) {
			return;
		}
		// 下架数据
		List<Long> noIds = list.stream().map(TblAssetNo::getId).toList();
		boolean update = new LambdaUpdateChainWrapper<>(baseMapper)
				.in(TblAssetNo::getId, noIds)
				.set(TblAssetNo::getSellPattern, SellPatternEnum.NORMAL.code())
				.update();
		isFalse(update, ErrorMessage.ASSET_SETTING_EX);
		// 解冻权益
		UnBlockAssetNoBenefitRequest unBlockAssetNoBenefitRequest = UnBlockAssetNoBenefitRequest.builder().assetNodIds(noIds).userId(uid).build();
		Boolean unBlockAssetNoBenefit = iInnerService.unBlockAssetNoBenefit(unBlockAssetNoBenefitRequest);
		log.info("off unBlockAssetNoBenefit result:{}", unBlockAssetNoBenefit);
	}

	@Override
	public List<TblAssetNo> getListByAssetId(Long assetId, Long uid, Long limit) {
		return new LambdaQueryChainWrapper<>(baseMapper)
				.eq(TblAssetNo::getAssetId, assetId)
				.eq(TblAssetNo::getAppUserId, uid)
				.orderByAsc(TblAssetNo::getReceiveTime)
				.last(Objects.nonNull(limit), "limit " + limit)
				.list();
	}
}
